home *** CD-ROM | disk | FTP | other *** search
/ Night Owl 6 / Night Owl's Shareware - PDSI-006 - Night Owl Corp (1990).iso / 039a / bccapp.zip / EDIT.C < prev    next >
C/C++ Source or Header  |  1991-09-15  |  7KB  |  382 lines

  1. /*
  2.  *
  3.  * Generic Field Edit System
  4.  *
  5.  * (C) 1990 Vision Software
  6.  *
  7.  * $Id: edit.c 1.2002 91/05/04 17:18:43 pcalvin beta $
  8.  *
  9.  * Comments:
  10.  *
  11.  * This class provides the user with the ability to edit multiple fields
  12.  * within a specific window.  Input validation is handled by Clipper-like
  13.  * pictures and validation functions.  In addition, validation may now be
  14.  * done by set validation (i.e using cent/pent to create fields)
  15.  *
  16.  * Bugs:
  17.  *
  18.  * None documented
  19.  *
  20.  */
  21. #include <stdio.h>
  22. #include <string.h>
  23.  
  24. #include <stdhdr.h>
  25.  
  26. #include <adl.h>
  27. #include <menu.h>
  28. #include <edit.h>
  29.  
  30. #include "lowlevel.h"
  31.  
  32. /*
  33.  * Simple construction.  Determines the Title and if the class should
  34.  * ask for exit confirmation
  35.  */
  36. EDIT::EDIT(BOOL fConfirm,SZ sz) : help(szNil)
  37.     {
  38.     fConfirmExit = fConfirm;
  39.     szTtl = sz;
  40.     pedLast = pedNil;
  41.     pedFirst = pedNil;
  42.     pedCurrent = pedNil;
  43.     pifCurrent = pifNil;
  44.     rowEditMax = rowNil;
  45.     colEditMax = colNil;
  46.     chLeft = '[';
  47.     chRight = ']';
  48.     }
  49.     
  50. /*
  51.  * Be sure to clean up any allocated memory..
  52.  */
  53. EDIT::~EDIT()
  54.     {
  55.     /*
  56.      * Delete any active Fields
  57.      */
  58.     while (pedLast != pedNil)
  59.         {
  60.         PED ped = (PED)pedLast->pifPrev;
  61.  
  62.         delete (pedLast);
  63.         pedLast = ped;
  64.         }
  65.  
  66.     /*
  67.      * Delete any active Information layers
  68.      */
  69.     while (pifCurrent != pifNil)
  70.         {
  71.         PIF pif = pifCurrent->pifPrev;
  72.  
  73.         delete (pifCurrent);
  74.         pifCurrent = pif;
  75.         }
  76.     }
  77.  
  78. /*
  79.  * Field creating.  May be constructed in various fashions, all end up being
  80.  * placed in chain..
  81.  */
  82. VOID EDIT::Field(ROW row,COL col,SZ szMsg,SZ sz,CCH cch,SZ szHelp,CENT cent,PENT pent,CENT centDefault)
  83.     {
  84.     PED ped = new ED(wndEdit,row,col,szMsg,sz,cch,szHelp,cent,pent,centDefault);
  85.  
  86.     Verify(FInsertNewPed(ped));
  87.     }
  88.  
  89. VOID EDIT::Field(ROW row,COL col,SZ szMsg,SZ sz,CHAR ch,CCH cch,SZ szHelp,SZ szDefault)
  90.     {
  91.     PED ped = new ED(wndEdit,row,col,szMsg,sz,ch,cch,szHelp,szDefault);
  92.  
  93.     Verify(FInsertNewPed(ped));
  94.     }
  95.  
  96. VOID EDIT::Field(ROW row,COL col,SZ szMsg,SZ sz,SZ szPicture,SZ szHelp,SZ szDefault)
  97.     {
  98.     PED ped = new ED(wndEdit,row,col,szMsg,sz,szPicture,szHelp,szDefault);
  99.  
  100.     Verify(FInsertNewPed(ped));
  101.     }
  102.  
  103. VOID EDIT::Title(ROW row,COL col,SZ sz)
  104.     {
  105.     PIF pif = new IF(wndEdit,row,col,sz);
  106.  
  107.     /*
  108.      * No constructors, must initialize ourselves
  109.      */
  110.     Assert(pif != pifNil);
  111.     pif->pifNext = pifNil;
  112.     pif->pifPrev = pifCurrent;
  113.  
  114.     /*
  115.      * Must consider titles when computing dimensions of window
  116.      */
  117.     rowEditMax = Max(row,rowEditMax);
  118.     colEditMax = Max(col+pif->ColRight(),colEditMax);
  119.  
  120.     if (pifCurrent != pifNil)
  121.         pifCurrent->pifNext = pif;
  122.  
  123.     pifCurrent = pif;
  124.     }
  125.  
  126. VOID EDIT::Read()
  127.     {
  128.     AssertSz(pedFirst != pedNil,"EDIT::Read() called without fields");
  129.  
  130.     CURSOR crs(fTrue);
  131.     BOOL fContinue = fTrue;
  132.     PED ped = pedLast;
  133.     PIF pif = pifCurrent;
  134.  
  135.     /*
  136.      * Compute dimensions of window
  137.      */
  138.     ROW rowTop = (rowGlobalWindowBottom - rowEditMax) >> 1;
  139.     ROW rowBottom = rowTop + rowEditMax + 1;
  140.     COL colLeft = (colGlobalWindowRight - colEditMax) >> 1;
  141.     COL colRight = colLeft + colEditMax + 1;
  142.  
  143.     /*
  144.      * Simple Text window
  145.      */
  146.     wndEdit = WINDOW(rowTop,colLeft,rowBottom,colRight,coBlack,coCyan,szTtl);
  147.     wndEdit.Open();
  148.  
  149.     /*
  150.      * Display any title information
  151.      */
  152.     while (pif != pifNil)
  153.         {
  154.         pif->SayMessage();
  155.         pif = pif->pifPrev;
  156.         }
  157.  
  158.     /*
  159.      * And titles/delimiters for messages..
  160.      */
  161.     while (ped != pedNil)
  162.         {
  163.         ped->SayMessage();
  164.         ped->ShowDelimiters(chLeft,chRight);
  165.  
  166.         ped = (PED)ped->pifPrev;
  167.         }
  168.  
  169.     /*
  170.      * Start editing at first entered field..
  171.      */
  172.     Rewind();
  173.     RedrawFields();
  174.  
  175.     while (fContinue)
  176.         {
  177.         /*
  178.          * Cursor position at current edit
  179.          */
  180.         wndEdit.SetRowCol(pedCurrent->RowEdit(),pedCurrent->ColEdit());
  181.  
  182.         /*
  183.          * Input handling is virtual..
  184.          */
  185.         fContinue = FHandleCd(CdInput());
  186.         }
  187.  
  188.     /*
  189.      * Cleanup the screen..
  190.      */
  191.     wndEdit.Close();
  192.     }
  193.  
  194. /*
  195.  * Adds PED to the current list..
  196.  */
  197. BOOL EDIT::FInsertNewPed(PED ped)
  198.     {
  199.     PointerAssert(ped);
  200.  
  201.     /*
  202.      * Keep track of the first one..
  203.      */
  204.     if (pedFirst == pedNil)
  205.         pedFirst = ped;
  206.  
  207.     /*
  208.      * Setup links between both..
  209.      */
  210.     ped->pifNext = pedNil;
  211.     ped->pifPrev = pedLast;
  212.     /*
  213.      * Determine the number of rows to display
  214.      */
  215.     rowEditMax = Max(ped->RowEdit(),rowEditMax);
  216.     colEditMax = Max(ped->ColRight(),colEditMax);
  217.  
  218.     if (pedLast != pedNil)
  219.         pedLast->pifNext = ped;
  220.  
  221.     pedLast = ped;
  222.  
  223.     return (fTrue);
  224.     }
  225.  
  226. /*
  227.  *    Force the edit to be considered "unchanged"
  228.  */
  229. VOID EDIT::ForceNoChanges()
  230.     {
  231.     PED ped = pedLast;
  232.  
  233.     while (ped != pedNil)
  234.         {
  235.         ped->SetUnchanged();
  236.         ped = (PED)ped->pifPrev;
  237.         }
  238.     }
  239.  
  240. /*
  241.  *    Answers if any of the fields have been modified.
  242.  */
  243. BOOL EDIT::FModified()
  244.     {
  245.     PED ped = pedLast;
  246.     BOOL fChanges = fFalse;
  247.  
  248.     while (!fChanges && ped != pedNil)
  249.         {
  250.         fChanges = ped->FModified();
  251.         ped = (PED)ped->pifPrev;
  252.         }
  253.  
  254.     return (fChanges);
  255.     }
  256.  
  257. VOID EDIT::RedrawFields()
  258.     {
  259.     CURSOR crs(fFalse);
  260.     REGISTER PED ped = pedLast;
  261.  
  262.     while (ped != pedNil)
  263.         {
  264.         ped->SetCursor();
  265.         ped->SayEdit((ped == pedCurrent) ? fTrue : fFalse);
  266.         ped = (PED)ped->pifPrev;
  267.         }
  268.     }
  269.  
  270. BOOL EDIT::FExit(void)
  271.     {
  272.     /*
  273.      * If user does not want to continue, edit will resume at the 
  274.      *    start.
  275.      */
  276.     NewPed(pedNil);
  277.     Rewind();
  278.     RedrawFields();
  279.     
  280.     /*
  281.      * And answer with user response
  282.      */
  283.     return (FAskSz("Terminate Current Edit?","Press \"Y\" to terminate edit, \"N\" to resume."));
  284.     }
  285.  
  286. VOID EDIT::Rewind()
  287.     {
  288.     NewPed(pedFirst);
  289.     }
  290.  
  291. VOID EDIT::ClearFields()
  292.     {
  293.     PED ped = pedLast;
  294.  
  295.     while (ped != pedNil)
  296.         {
  297.         ped->Clear();
  298.         ped = (PED)ped->pifPrev;
  299.         }
  300.     }
  301.  
  302. VOID EDIT::Delimiters(CHAR chL,CHAR chR)
  303.     {
  304.     chLeft = chL;
  305.     chRight = chR;
  306.     }
  307.  
  308.  
  309. BOOL EDIT::FHandleCd(CD cd)
  310.     {
  311.     BOOL fContinue = fTrue;
  312.  
  313.     switch (cd)
  314.         {
  315.     case cdEscape:
  316.         if (!fConfirmExit || FExit())
  317.             fContinue = fFalse;
  318.  
  319.         break;
  320.     case cdReturn:
  321.     case cdCursorDown:
  322.         if (pedCurrent->FValidate())
  323.             {
  324.             if (pedCurrent->pifNext != pedNil)
  325.                 NewPed((PED)pedCurrent->pifNext);
  326.             else if (cd == cdReturn && (!fConfirmExit || FExit()))
  327.                 fContinue = fFalse;
  328.             }
  329.         break;
  330.     case cdCursorUp:
  331.         if (pedCurrent->FValidate())
  332.             {
  333.             if (pedCurrent->pifPrev != pedNil)
  334.                 NewPed((PED)pedCurrent->pifPrev);
  335.             }
  336.         break;
  337.     case cdCursorLeft:
  338.         pedCurrent->CursorLeft();
  339.         break;
  340.     case cdCursorRight:
  341.         pedCurrent->CursorRight();
  342.         break;
  343.     case cdBackSpace:
  344.         Verify(pedCurrent->FDelete());
  345.         break;
  346.     default:
  347.         Verify(pedCurrent->FInsertCd(cd));
  348.         break;
  349.         }
  350.  
  351.     return (fContinue);
  352.     }
  353.  
  354. /*
  355.  * Answers with the last ED() structure created.
  356.  */
  357. PED EDIT::PedQuery()
  358.     {
  359.     return (pedLast);
  360.     }
  361.  
  362. /*
  363.  * Redraws current and new edit.
  364.  */
  365. VOID EDIT::NewPed(PED ped)
  366.     {
  367.     if (pedCurrent != pedNil)
  368.         {
  369.         pedCurrent->SayEdit(fFalse);
  370.         }
  371.  
  372.     if (ped != pedNil)
  373.         {
  374.         ped->SayEdit(fTrue);
  375.         ped->SetCursor(); 
  376.         ped->UpdateHelp(help);
  377.         }
  378.         
  379.     pedCurrent = ped;
  380.     }
  381.  
  382.